package com.ebupt.migu.music.elasticsearch.controller;

import java.io.IOException;
import java.util.Collections;
import java.util.Map;

import org.apache.http.HttpEntity;
import org.apache.http.entity.ContentType;
import org.apache.http.nio.entity.NStringEntity;
import org.apache.http.util.EntityUtils;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
import org.elasticsearch.action.admin.indices.get.GetIndexRequest;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.client.*;
import org.elasticsearch.xcontent.XContentType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import com.ebupt.migu.music.elasticsearch.entity.Entity;
import com.google.gson.Gson;
import com.sun.istack.NotNull;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import lombok.extern.slf4j.Slf4j;

/**
 * @author admin
 */
@Slf4j
@RestController
@RequestMapping("/es")
public class ElasticsearchController {

    @Autowired
    private RestHighLevelClient client;
    @Autowired
    private RestClient restClient;

    Gson gson = new Gson();

    /**
     * 创建索引
     * 
     * @param index
     * @throws IOException
     */
    @RequestMapping(value = "/createIndex")
    public String createIndex(String index) throws IOException {
        CreateIndexRequest request = new CreateIndexRequest(index);
        CreateIndexResponse createIndexResponse = client.indices().create(request, RequestOptions.DEFAULT);
        String ret = gson.toJson(createIndexResponse);
        System.out.println("createIndex: " + ret);
        return ret;
    }

    /**
     * 判断索引是否存在
     * 
     * @param index
     * @return
     * @throws IOException
     */
    @RequestMapping(value = "/existsIndex")
    @ResponseBody
    public boolean existsIndex(String index) throws IOException {
        GetIndexRequest request = new GetIndexRequest();
        request.indices(index);
        boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);
        System.out.println("existsIndex: " + exists);
        return exists;
    }

    /**
     * 增加记录
     * 
     * @param index
     * @param type
     * @param entity
     * @throws IOException
     */
    @RequestMapping(value = "/add", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
    @ResponseBody
    public void add(String index, String type, @NotNull @RequestBody Entity entity) throws IOException {
        IndexRequest indexRequest = new IndexRequest(index, type, entity.getId().toString());

        System.out.println("index=" + index);
        System.out.println("type=" + type);
        System.out.println("entity=" + gson.toJson(entity));

        indexRequest.source(gson.toJson(entity), XContentType.JSON);
        IndexResponse indexResponse = client.index(indexRequest, RequestOptions.DEFAULT);
        System.out.println("add: " + gson.toJson(indexResponse));
    }

    /**
     * 获取记录信息
     * 
     * @param index
     * @param type
     * @param id
     * @throws IOException
     */
    @RequestMapping(value = "/get")
    @ResponseBody
    public String get(String index, String type, Long id) throws IOException {
        GetRequest getRequest = new GetRequest(index, type, id.toString());// index:库，type:表，id:
        GetResponse getResponse = client.get(getRequest, RequestOptions.DEFAULT);
        String ret = gson.toJson(getResponse);
        System.out.println("get: " + ret);
        return ret;
    }

    @RequestMapping(value = "/getTest")
    @ResponseBody
    public String getTest(String msisdn) throws IOException {
        // msisdn="18379828783";
        String esIndex = "rfment";
        String esType = "static_users";

        long BUFFER_SIZE = 520 * 1024 * 1024;
        // 拼装dsl json语句
        StringBuilder requestBody = new StringBuilder();
        requestBody.append("{\"size\":10,");
        // 聚合查询DSL语句，_source为空，仅返回聚合查询数据，加快查询效率
        // requestBody.append("\"_source\":[\"\"],");
        requestBody.append("\"from\": 0,");
        // requestBody.append("\"query\":{\"term\":{\"msisdn\":").append(msisdn).append("}}}}");
        // requestBody.append("\"query\":{\"match\":{\"msisdn\":").append(msisdn).append("}}}}");
        // 前匹配搜索与过滤（prefix）相当于 like te%
        requestBody.append("\"query\":{\"prefix\":{\"msisdn\":").append(msisdn).append("}}}}");
        // es路径
        String esPath = String.format("/%s/%s/%s", esIndex, esType, "_search");
        System.out.println(esPath);
        HttpEntity entity = new NStringEntity(requestBody.toString(), ContentType.APPLICATION_JSON);
        Map<String, String> params = Collections.emptyMap();
        HttpAsyncResponseConsumerFactory.HeapBufferedResponseConsumerFactory consumerFactory =
            new HttpAsyncResponseConsumerFactory.HeapBufferedResponseConsumerFactory((int)BUFFER_SIZE);
        // Response indexResponse = restClient.performRequest(null == requestType ? "GET" : requestType, esPath,
        // params, entity, consumerFactory);
        Request request = new Request("GET", esPath);
        request.setEntity(entity);
        Response indexResponse = restClient.performRequest(request);
        String result = EntityUtils.toString(indexResponse.getEntity());
        String ret = gson.toJson(result);
        System.out.println("get: " + ret);
        System.out.println("Converting to JSON");
        JSONObject jsonObject = new JSONObject(result);
        JSONObject hits = jsonObject.getJSONObject("hits");
        JSONArray hitsArray = hits.getJSONArray("hits");
        JSONObject source = null;
        String u_id = null;
        String idfa = null;
        String imei = null;
        int id = 0;
        for (int i = 0; i < hitsArray.size(); i++) {
            JSONObject obj = hitsArray.getJSONObject(i);
            source = obj.getJSONObject("_source");
            u_id = source.getStr("u_id");
            idfa = source.getStr("idfa");
            imei = source.getStr("imei");
            msisdn = source.getStr("msisdn");
        }
        JSONObject jsonBody = new JSONObject();
        jsonBody.put("u_id", u_id);
        jsonBody.put("idfa", idfa);
        jsonBody.put("imei", imei);
        jsonBody.put("msisdn", msisdn);
        System.out.println("Response --->" + jsonBody.toString());
        return jsonBody.toString();
    }

}
